package com.ddm.service.impl.vxImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ddm.constant.MessageConstant;
import com.ddm.dto.vxDTO.QuestionAnalysis;
import com.ddm.dto.vxDTO.ScoreDTO;
import com.ddm.entity.vxEntity.Exam;
import com.ddm.entity.vxEntity.Score;
import com.ddm.entity.vxEntity.Test;
import com.ddm.entity.vxEntity.User;
import com.ddm.exception.DataErrorException;
import com.ddm.mapper.ExamMapper;
import com.ddm.mapper.ScoreMapper;
import com.ddm.mapper.TestMapper;
import com.ddm.mapper.UserMapper;
import com.ddm.result.Result;
import com.ddm.service.vxService.ExamService;
import com.ddm.service.vxService.ScoreService;
import com.ddm.vo.vxVo.ContestVo;
import com.ddm.vo.vxVo.ScoreVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author horizon
 * @since 2025-01-17
 */
@Service
public class ScoreServiceImpl extends ServiceImpl<ScoreMapper, Score> implements ScoreService {

    @Autowired
    ScoreMapper scoreMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ExamMapper examMapper;
    @Autowired
    ExamService examService;
    @Autowired
    TestMapper testMapper;

    @Override
    public ContestVo getScore(Long examId) {
        // 1. 获取考试信息
        Exam exam = examMapper.selectById(examId);
        if (exam == null) {
            throw new DataErrorException(MessageConstant.EXAM_NOT_FOUND);
        }
        String examName = exam.getExamName();
        if (examName == null) {
            throw new DataErrorException(MessageConstant.EXAM_NAME_EMPTY);
        }

        // 2. 获取所有成绩，按分数降序排列
        LambdaQueryWrapper<Score> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Score::getExamId, examId)
               .orderByDesc(Score::getTotalScores);
        List<Score> scores = scoreMapper.selectList(wrapper);
        if (scores.isEmpty()) {
            throw new DataErrorException(MessageConstant.EXAM_NO_PARTICIPANTS);
        }

        // 3. 获取有效用户信息并计算获奖人数
        List<Long> userIds = scores.stream().map(Score::getUserId).collect(Collectors.toList());
        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.in(User::getId, userIds)
                  .eq(User::getDeleted, 0); // 只查询未删除的用户
        
        // 获取有效用户列表
        List<User> userList = userMapper.selectList(userWrapper);
        Map<Long, String> users = userList.stream().collect(Collectors.toMap(User::getId, User::getUserName));
        
        // 计算获奖人数（基于所有成绩记录，与排行榜保持一致）
        int totalParticipants = scores.size();
        int firstPrizeCount = calculatePrizeCount(totalParticipants, exam.getFirstPrizeRatio());
        int secondPrizeCount = calculatePrizeCount(totalParticipants, exam.getSecondPrizeRatio());
        int thirdPrizeCount = calculatePrizeCount(totalParticipants, exam.getThirdPrizeRatio());

        // 5. 构建成绩列表并计算获奖信息（只包含未删除用户的成绩）
        ArrayList<ScoreVO> scoreVOS = new ArrayList<>();
        int totalScore = 0;
        int currentRank = 1;
        int validScoreCount = 0; // 有效成绩数量

        for (Score score : scores) {
            String userName = users.get(score.getUserId());
            if (userName == null) {
                // 跳过已删除用户的成绩记录
                continue;
            }

            totalScore += score.getTotalScores();
            validScoreCount++;
            
            // 创建ScoreVO
            ScoreVO scoreVO = new ScoreVO();
            scoreVO.setExamName(examName);
            scoreVO.setUserName(userName);
            scoreVO.setTotalScores(score.getTotalScores());
            scoreVO.setRank(currentRank);

            // 计算获奖等级和比例（使用优化版本，与排行榜保持一致）
            String prizeLevel = getPrizeLevelOptimized(currentRank, totalParticipants, 
                                                     exam.getFirstPrizeRatio(), exam.getSecondPrizeRatio(), exam.getThirdPrizeRatio());
            String prizeRatio = getPrizeRatioOptimized(currentRank, totalParticipants,
                                                     exam.getFirstPrizeRatio(), exam.getSecondPrizeRatio(), exam.getThirdPrizeRatio());
            
            scoreVO.setPrizeLevel(prizeLevel);
            scoreVO.setPrizeRatio(prizeRatio);
            
            scoreVOS.add(scoreVO);
            currentRank++;
        }

        // 如果没有有效成绩，抛出异常
        if (validScoreCount == 0) {
            throw new DataErrorException(MessageConstant.EXAM_ALL_USERS_DELETED);
        }

        // 6. 构建返回结果
        ContestVo contestVo = new ContestVo();
        contestVo.setExamName(examName);
        contestVo.setScoreVOList(scoreVOS);
        double averageScore = (double) totalScore / scores.size();
        contestVo.setAverageScore(averageScore * 10 / 10.0);
        
        // 设置获奖统计信息（与排行榜保持一致）
        contestVo.setTotalParticipants(totalParticipants); // 基于所有成绩记录
        contestVo.setFirstPrizeCount(firstPrizeCount);
        contestVo.setSecondPrizeCount(secondPrizeCount);
        contestVo.setThirdPrizeCount(thirdPrizeCount);
        contestVo.setFirstPrizeRatio(exam.getFirstPrizeRatio());
        contestVo.setSecondPrizeRatio(exam.getSecondPrizeRatio());
        contestVo.setThirdPrizeRatio(exam.getThirdPrizeRatio());

        return contestVo;
    }

    @Override
    public Result<List<ScoreVO>> getUserScore(Long id) {
        LambdaQueryWrapper<Score> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Score::getUserId, id);
        List<Score> list = scoreMapper.selectList(wrapper);

        ArrayList<ScoreVO> scoreVOS = new ArrayList<>();

        for (Score score : list) {
            ScoreVO scoreVO = new ScoreVO();
            Long examId = score.getExamId();

            // 设置 ScoreVO 的属性
            scoreVO.setExamName(examMapper.selectById(examId).getExamName());
            scoreVO.setUserName(userMapper.selectById(id).getUserName());
            scoreVO.setTotalScores(score.getTotalScores());

            // 将 ScoreVO 添加到列表中
            scoreVOS.add(scoreVO);
        }

        return Result.success(scoreVOS);
    }

    @Override
    public Result<ScoreVO> getUserExamResult(Long userId, Long examId) {
        // 查询用户的考试记录
        LambdaQueryWrapper<Score> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Score::getUserId, userId)
                .eq(Score::getExamId, examId);
        Score score = scoreMapper.selectOne(wrapper);
        
        if (score == null) {
            throw new DataErrorException("未找到该考试记录");
        }

        // 查询考试信息
        Exam exam = examMapper.selectById(examId);
        if (exam == null) {
            throw new DataErrorException("考试信息不存在");
        }

        // 查询用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new DataErrorException("用户信息不存在");
        }

        // 查询用户的答题详情，计算统计数据
        LambdaQueryWrapper<Test> testWrapper = new LambdaQueryWrapper<>();
        testWrapper.eq(Test::getUserId, userId)
                  .eq(Test::getExamId, examId);
        List<Test> tests = testMapper.selectList(testWrapper);
        
        int correctQuestionNum = 0;
        int wrongQuestionNum = 0;
        int totalAnswerTime = 0;
        
        for (Test test : tests) {
            if (test.getIsCorrect()) {
                correctQuestionNum++;
            } else {
                wrongQuestionNum++;
            }
            totalAnswerTime += test.getAnswerTime();
        }

        // 构建ScoreVO
        ScoreVO scoreVO = new ScoreVO();
        scoreVO.setUserName(user.getUserName());
        scoreVO.setExamName(exam.getExamName());
        scoreVO.setTotalScores(score.getTotalScores());
        scoreVO.setAverageScore(null); // 平均分暂时设为null，因为这是单次考试
        scoreVO.setCorrectQuestionNum(correctQuestionNum);
        scoreVO.setWrongQuestionNum(wrongQuestionNum);
        scoreVO.setTotalAnswerTime(totalAnswerTime);
        scoreVO.setVersion(score.getVersion());
        scoreVO.setBonusPoints(score.getTotalScores()); // 积分等于分数

        // 获取题目解析信息
        List<QuestionAnalysis> questionList = examService.analysisQuestion(examId);
        scoreVO.setQuestionList(questionList);

        return Result.success(scoreVO);
    }

    /**
     * 计算获奖人数
     */
    private int calculatePrizeCount(int totalParticipants, BigDecimal ratio) {
        if (ratio == null || ratio.compareTo(BigDecimal.ZERO) <= 0) {
            return 0;
        }
        
        // 特殊处理：当参与人数很少时，确保至少有人能获奖
        if (totalParticipants <= 3) {
            // 如果只有1-3人参与，第1名获得一等奖
            if (totalParticipants == 1) {
                return 1;
            } else if (totalParticipants == 2) {
                // 2人参与：第1名一等奖，第2名二等奖
                return ratio.compareTo(BigDecimal.valueOf(0.5)) >= 0 ? 1 : 0;
            } else {
                // 3人参与：第1名一等奖，第2名二等奖，第3名三等奖
                if (ratio.compareTo(BigDecimal.valueOf(0.33)) >= 0) {
                    return 1;
                } else if (ratio.compareTo(BigDecimal.valueOf(0.66)) >= 0) {
                    return 2;
                } else {
                    return 3;
                }
            }
        }
        
        // 正常计算
        BigDecimal count = ratio.multiply(BigDecimal.valueOf(totalParticipants));
        int result = count.setScale(0, RoundingMode.HALF_UP).intValue();
        
        // 确保至少有人获奖（如果比例不为0）
        if (result == 0 && ratio.compareTo(BigDecimal.ZERO) > 0) {
            return 1;
        }
        
        return result;
    }

    /**
     * 获取获奖等级
     */
    private String getPrizeLevel(int rank, int firstPrizeCount, int secondPrizeCount, int thirdPrizeCount) {
        if (rank <= firstPrizeCount) {
            return "一等奖";
        } else if (rank <= firstPrizeCount + secondPrizeCount) {
            return "二等奖";
        } else if (rank <= firstPrizeCount + secondPrizeCount + thirdPrizeCount) {
            return "三等奖";
        } else {
            return "未获奖";
        }
    }

    /**
     * 获取获奖比例
     */
    private String getPrizeRatio(int rank, int firstPrizeCount, int secondPrizeCount, int thirdPrizeCount,
                                BigDecimal firstRatio, BigDecimal secondRatio, BigDecimal thirdRatio) {
        if (rank <= firstPrizeCount) {
            return firstRatio != null ? firstRatio.multiply(BigDecimal.valueOf(100)).toString() + "%" : "0%";
        } else if (rank <= firstPrizeCount + secondPrizeCount) {
            return secondRatio != null ? secondRatio.multiply(BigDecimal.valueOf(100)).toString() + "%" : "0%";
        } else if (rank <= firstPrizeCount + secondPrizeCount + thirdPrizeCount) {
            return thirdRatio != null ? thirdRatio.multiply(BigDecimal.valueOf(100)).toString() + "%" : "0%";
        } else {
            return "0%";
        }
    }

    /**
     * 获取获奖等级（优化版本，考虑小规模竞赛）
     */
    private String getPrizeLevelOptimized(int rank, int totalParticipants, BigDecimal firstRatio, BigDecimal secondRatio, BigDecimal thirdRatio) {
        // 特殊处理小规模竞赛
        if (totalParticipants == 1) {
            return "一等奖";
        } else if (totalParticipants == 2) {
            return rank == 1 ? "一等奖" : "二等奖";
        } else if (totalParticipants == 3) {
            if (rank == 1) return "一等奖";
            else if (rank == 2) return "二等奖";
            else return "三等奖";
        }
        
        // 正常计算
        int firstPrizeCount = calculatePrizeCount(totalParticipants, firstRatio);
        int secondPrizeCount = calculatePrizeCount(totalParticipants, secondRatio);
        int thirdPrizeCount = calculatePrizeCount(totalParticipants, thirdRatio);
        
        if (rank <= firstPrizeCount) {
            return "一等奖";
        } else if (rank <= firstPrizeCount + secondPrizeCount) {
            return "二等奖";
        } else if (rank <= firstPrizeCount + secondPrizeCount + thirdPrizeCount) {
            return "三等奖";
        } else {
            return "未获奖";
        }
    }

    /**
     * 获取获奖比例（优化版本，考虑小规模竞赛）
     */
    private String getPrizeRatioOptimized(int rank, int totalParticipants, BigDecimal firstRatio, BigDecimal secondRatio, BigDecimal thirdRatio) {
        // 特殊处理小规模竞赛
        if (totalParticipants == 1) {
            return "100%";
        } else if (totalParticipants == 2) {
            return rank == 1 ? "50%" : "50%";
        } else if (totalParticipants == 3) {
            if (rank == 1) return "33%";
            else if (rank == 2) return "33%";
            else return "33%";
        }
        
        // 正常计算
        int firstPrizeCount = calculatePrizeCount(totalParticipants, firstRatio);
        int secondPrizeCount = calculatePrizeCount(totalParticipants, secondRatio);
        int thirdPrizeCount = calculatePrizeCount(totalParticipants, thirdRatio);
        
        if (rank <= firstPrizeCount) {
            return firstRatio != null ? firstRatio.multiply(BigDecimal.valueOf(100)).toString() + "%" : "0%";
        } else if (rank <= firstPrizeCount + secondPrizeCount) {
            return secondRatio != null ? secondRatio.multiply(BigDecimal.valueOf(100)).toString() + "%" : "0%";
        } else if (rank <= firstPrizeCount + secondPrizeCount + thirdPrizeCount) {
            return thirdRatio != null ? thirdRatio.multiply(BigDecimal.valueOf(100)).toString() + "%" : "0%";
        } else {
            return "0%";
        }
    }

}
